package com.c2soft.ncmxSocket;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;

public class SocketClient {
	static Map<String, String> tokenIdSymbolMap;
	static{
		try {
			  tokenIdSymbolMap = readMCXContract();
			  System.out.println("tokenIdSymbolMap="+tokenIdSymbolMap);
		} catch (IOException e1) {
			
			e1.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		Socket socket = null;
		Short txnCode = 1001;
		
		
		String userName = padString("demo", 25);
		String password = padString("demo@123", 25);
		String apiCode = padString("SAT", 20);

		byte[] loginReqByte1 = new byte[2];
		loginReqByte1[0] = (byte) (txnCode & 0xff);
		loginReqByte1[1] = (byte) ((txnCode >> 8) & 0xff);

		loginReqByte1 = concat(loginReqByte1, userName.getBytes(),
				password.getBytes(), apiCode.getBytes());
		try {
			// socket = new Socket("127.0.0.1", 9014);
			socket = new Socket("193.34.144.236", 8102);
			//socket = new Socket("80.241.222.160", 8102);

			System.out.println("Connected to server...sending echo string");
			InputStream in = socket.getInputStream();

			OutputStream out = socket.getOutputStream();

			// send loginrequest
			out.write(loginReqByte1);

			while (true) {
				int totalBytesRcvd = 0; // Total bytes received so far

				int bytesRcvd = 0; // Bytes received in last read

				byte[] loginResByte = new byte[5000];
				
				//HashSet for unique data
				Set<QuoteData> changedQuoteData=new HashSet<QuoteData>();

				if ((bytesRcvd = in.read(loginResByte, totalBytesRcvd,
						loginResByte.length)) == -1) {

					throw new SocketException("Connection closed prematurely");
				} else {
					if (bytesRcvd > 0) {
						short val = ByteBuffer.wrap(loginResByte)
								.order(java.nio.ByteOrder.LITTLE_ENDIAN)
								.getShort();

						switch (val) {
						case 1051: {
							int userID = ByteBuffer.wrap(loginResByte, 2, 4)
									.order(java.nio.ByteOrder.LITTLE_ENDIAN)
									.getInt();
							short oLoginStat = ByteBuffer
									.wrap(loginResByte, 6, 2)
									.order(java.nio.ByteOrder.LITTLE_ENDIAN)
									.getShort();
							// String exchs = ByteBuffer.wrap(loginResByte, 8,
							// 25).toString();
							byte[] oServIP = new byte[16];
							byte[] oftpUserName = new byte[20];
							byte[] oftpPwd = new byte[20];
							ByteBuffer.wrap(loginResByte, 8, 16).get(oServIP);
							String serverIP = new String(oServIP);

							ByteBuffer.wrap(loginResByte, 24, 44).get(
									oftpUserName);
							String ftpUserName = new String(oftpUserName);

							ByteBuffer.wrap(loginResByte, 24, 44).get(oftpPwd);
							String ftpPwd = new String(oftpPwd);
							System.out.println("serverIP=" + serverIP
									+ " \n ftpUserName=" + ftpUserName
									+ "\n ftpPwd=" + ftpPwd);
						}
							break;
						case 50: {
							short noofPkt = ByteBuffer.wrap(loginResByte, 2, 2)
									.order(java.nio.ByteOrder.LITTLE_ENDIAN)
									.getShort();
							short exchID = ByteBuffer.wrap(loginResByte, 4, 2)
									.order(java.nio.ByteOrder.LITTLE_ENDIAN)
									.getShort();

							int constant = noofPkt * 82;
							constant += 100;
							byte[] result = new byte[constant];
							ByteBuffer.wrap(loginResByte, 4, result.length)
									.get(result);
							int index = 0;
                            
							for (int pktInd = 0; pktInd <= noofPkt; pktInd++) {
								byte[] qutPkt = new byte[86];

								try {
									ByteBuffer.wrap(result, index,
											qutPkt.length).get(qutPkt);
								} catch (Exception e) {
									break;
								}

								short exchID_ = ByteBuffer
										.wrap(qutPkt, 0, 2)
										.order(java.nio.ByteOrder.LITTLE_ENDIAN)
										.getShort();
								int tokenID = ByteBuffer
										.wrap(qutPkt, 2, 4)
										.order(java.nio.ByteOrder.LITTLE_ENDIAN)
										.getInt();
								String symbol=tokenIdSymbolMap.get(String.valueOf(tokenID) );
								
								
								int bid1 = ByteBuffer
										.wrap(qutPkt, 6, 4)
										.order(java.nio.ByteOrder.LITTLE_ENDIAN)
										.getInt();
								int bidQ1 = ByteBuffer
										.wrap(qutPkt, 10, 4)
										.order(java.nio.ByteOrder.LITTLE_ENDIAN)
										.getInt();
								int ask1 = ByteBuffer
										.wrap(qutPkt, 14, 4)
										.order(java.nio.ByteOrder.LITTLE_ENDIAN)
										.getInt();
								int askQ1 = ByteBuffer
										.wrap(qutPkt, 18, 4)
										.order(java.nio.ByteOrder.LITTLE_ENDIAN)
										.getInt();

								int ltp = ByteBuffer
										.wrap(qutPkt, 22, 4)
										.order(java.nio.ByteOrder.LITTLE_ENDIAN)
										.getInt();
								int ltq = ByteBuffer
										.wrap(qutPkt, 26, 4)
										.order(java.nio.ByteOrder.LITTLE_ENDIAN)
										.getInt();
								int ltt = ByteBuffer
										.wrap(qutPkt, 30, 4)
										.order(java.nio.ByteOrder.LITTLE_ENDIAN)
										.getInt();
								int open = ByteBuffer
										.wrap(qutPkt, 34, 4)
										.order(java.nio.ByteOrder.LITTLE_ENDIAN)
										.getInt();
								int high = ByteBuffer
										.wrap(qutPkt, 38, 4)
										.order(java.nio.ByteOrder.LITTLE_ENDIAN)
										.getInt();
								int low = ByteBuffer
										.wrap(qutPkt, 42, 4)
										.order(java.nio.ByteOrder.LITTLE_ENDIAN)
										.getInt();
								int close = ByteBuffer
										.wrap(qutPkt, 46, 4)
										.order(java.nio.ByteOrder.LITTLE_ENDIAN)
										.getInt();
								double tbq = ByteBuffer
										.wrap(qutPkt, 50, 8)
										.order(java.nio.ByteOrder.LITTLE_ENDIAN)
										.getDouble();
								double tsq = ByteBuffer
										.wrap(qutPkt, 58, 8)
										.order(java.nio.ByteOrder.LITTLE_ENDIAN)
										.getDouble();
								double vol = ByteBuffer
										.wrap(qutPkt, 66, 8)
										.order(java.nio.ByteOrder.LITTLE_ENDIAN)
										.getDouble();
								double openInt = ByteBuffer
										.wrap(qutPkt, 74, 8)
										.order(java.nio.ByteOrder.LITTLE_ENDIAN)
										.getDouble();
								
								QuoteData quoteData = null;
								if(symbol !=null){
								 quoteData = new QuoteData(exchID_,
										tokenID,symbol, bid1, bidQ1, ask1, askQ1, ltp,
										ltq, ltt, open, high, low, close, tbq,
										tsq, vol, openInt);
								 System.out.println(quoteData);
								changedQuoteData.add(quoteData);
								}
								
								index += 86;
								
							}
						}
							break;
						}
						System.out.println("<<----- Case: = " + val
								+ "       done!!---->>");
					}
				}
				System.out.println("Data Size: "+changedQuoteData.size());
				System.out.println("HashSet ="+changedQuoteData);
				System.out.println("Will return to while!!!");
			}

		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				socket.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	private static String padString(String str, int leng) {
		StringBuilder sb = new StringBuilder(str);
		for (int i = str.length(); i <= leng; i++)
			sb.append(" ");
		return sb.toString();
	}

	private static byte[] concat(byte[]... arrays) {
		int lengh = 0;
		for (byte[] array : arrays) {
			lengh += array.length;
		}
		byte[] result = new byte[lengh];
		int pos = 0;
		for (byte[] array : arrays) {
			for (byte element : array) {
				result[pos] = element;
				pos++;
			}
		}
		return result;
	}

	private static Map<String, String> readMCXContract() throws IOException {
		
		/*	
		 * serverIP=193.34.144.236   
 			ftpUserName=historical          
 			ftpPwd=historical 
		 */
		File file = new File("F://FTP//MCX.txt");
		Map<String, String> tokenIdSymbolMap = new HashMap<String, String>();
		// String string = FileUtils.readFileToString(file);
		List<String> lines = FileUtils.readLines(file);
		for (String line : lines) {
			if (StringUtils.isNotBlank(line)) {
				// System.out.println("line:" + line);
				String[] strArray = StringUtils.split(line, ",");
				tokenIdSymbolMap.put(strArray[1], strArray[2]);
			}
		}

		return tokenIdSymbolMap;

	}
}